﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Input;
namespace EmlViewer.Behaviours
{
    public static class DropBehaviour
    {
        #region DandDirectories (Attached DependencyProperty)
        public static readonly DependencyProperty DandDirectoriesProperty =
            DependencyProperty.RegisterAttached("DandDirectories", 
            typeof(ICommand), typeof(DropBehaviour), 
            new PropertyMetadata(OnDandDirectoriesChanged));
        public static void SetDandDirectories(DependencyObject o, ICommand value)
        {
            o.SetValue(DandDirectoriesProperty, value);
        }
        public static ICommand GetDandDirectories(DependencyObject o)
        {
            return (ICommand)o.GetValue(DandDirectoriesProperty);
        }
        private static void OnDandDirectoriesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var g = d as UIElement;
            if (g == null) return;
            var ic = e.NewValue as ICommand;
            if (ic == null) return;
            g.Drop += (s, a) =>
            {
                IEnumerable<string> directoryNames = ExtractDroppedObjectNames(a);
                if (directoryNames.All(Directory.Exists))
                {
                    if (directoryNames != null)
                    {
                        if (ic.CanExecute(directoryNames))
                        {
                            ic.Execute(directoryNames);
                        }
                    }
                }
            };
        }
        #endregion
        #region DandFiles (Attached DependencyProperty)
        public static readonly DependencyProperty DandFilesProperty =
            DependencyProperty.RegisterAttached("DandFiles", typeof (ICommand), typeof (DropBehaviour),
                new PropertyMetadata(OnDandFilesChanged));
        public static void SetDandFiles(DependencyObject o, ICommand value)
        {
            o.SetValue(DandFilesProperty, value);
        }
        public static ICommand GetDandFiles(DependencyObject o)
        {
            return (ICommand) o.GetValue(DandFilesProperty);
        }
        private static void OnDandFilesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var g = d as UIElement;
            if (g == null) return;
            var ic = e.NewValue as ICommand;
            if (ic == null) return;
            g.Drop += (s, a) =>
            {
                IEnumerable<string> fileNames = ExtractDroppedObjectNames(a);
                if (fileNames.All(File.Exists))
                {
                    if (fileNames != null)
                    {
                        if (ic.CanExecute(fileNames))
                        {
                            ic.Execute(fileNames);
                        }
                    }
                }
            };
        }
        #endregion
        private static IEnumerable<string> ExtractDroppedObjectNames(DragEventArgs dda)
        {
            var result = new List<string>();
            try
            {
                if (dda != null)
                {
                    IDataObject ido = dda.Data;
                    if (ido != null)
                    {
                        var names = ido.GetData(DataFormats.FileDrop) as string[];
                        if (names != null && names.Length > 0)
                        {
                            result.AddRange(names);
                        }
                    }
                }
            }
            catch (Exception)
            {
                return null;
            }
            return result;
        }
    }
}